#include "resource.h"
#include "..\ProcessHistory\MainFrm.h"
#include "AboutDlg.h"
#include "ph.h"
#include "screen.h"
#include "query.h"
#include "wtl\wtl.h"
#include "..\phshared\PHShared.h"
//#include "SettingsDlg.h"
#include <boost/thread/thread.hpp>

using namespace std;
using namespace boost::posix_time;
using namespace boost;
using namespace boost::gregorian;

/*const UINT CMainFrame::m_uTaskbarBtnCreatedMsg =
  RegisterWindowMessage ( _T("TaskbarButtonCreated") );*/

extern PHDisplay phd;
PH ph_instance;
extern PHQuery phq;
ptime wr,wl;

void PHCOMError(HRESULT hr,std::string s,int line, std::string file)
{	
	std::ostringstream os;
	os<<"0x"<<std::hex<<hr;
	os<<" "<<s;
	PHTrace(os.str(),line,file);
}

mutex work_mtx;
int direction;
void RF1(string where);

bool PHJump(ptime wl,int direction)
{
	ostringstream os;

	if(direction==-1)
		os<<"SELECT MAX(Destruction) From Process WHERE Destruction <"<<BoostToSQLite(wl)<<";";

	if(direction==1)
		os<<"SELECT MIN(CreationTime) FROM Process WHERE Creation>"<<BoostToSQLite(wr)<<";";

	sqlite3 *db;
	sqlite3_stmt* stmt;
	db = OpenDB();
	if(sqlite3_prepare(db,os.str().c_str(),-1,&stmt,NULL)!=SQLITE_OK)
		DBError(sqlite3_errmsg(db),__LINE__,__FILE__);
	ptime result;
	bool r;
	if(sqlite3_step(stmt)== SQLITE_ROW )
	{	
		string file=(char*)sqlite3_column_text(stmt,0);
		result=time_from_string(file);
		r=true;
	}
	else
		r=false;
	sqlite3_finalize(stmt);
	sqlite3_close(db);

	string SQLw=phq.Construct(result);
	RF1(SQLw);
	return r;
}


void RFWorker()
{
	//mutex::scoped_lock work_sl(work_mtx);
	
	phd._complete=false;
	if(phq.Query()!=0)
	{
		::SetWindowText(ph_instance._hWndStatusBar,"Working...");
		phd.UpdateWindow();
		phd._complete=true;
		::PostMessage (ph_instance._hWnd, UWM_DOWNLOAD_PROGRESS, 1, 0 );
			
	  // Remove the progress bar from the taskbar button.
        /*if ( m_pTaskbarList )
		{
			//m_pTaskbarList->SetProgressValue ( m_hWnd, 0, 0 );	
          HRESULT hr=  m_pTaskbarList->SetProgressState ( m_hWnd, TBPF_NOPROGRESS );
		  PHCOMError(hr,"Error setting progress",__LINE__,__FILE__);
		}*/
	}
	else
	{
	
	//check for processes further than one screen width
		PHJump(wl,direction);
		//::MessageBox(ph_instance._hWnd,"No more processes in database","No processes",MB_OK);
			phd._WinRight=wr;
			phd._WinLeft=wl;
			phd._complete=true;//clears screen on refresh without this
			work_mtx.unlock();
	}
	//
}

void /*CMainFrame::*/RF1(string where)
{
	phq.SetSQL(where);
	thread st(&RFWorker);
	RECT r;
	/*TODO ::GetWindowRect(m_hWnd,&r);
	m_wndHorzSplit.SetSplitterPos ((int)(((float)r.bottom/10)*7.5));*/
	
}

// left and right arrows 
//-> <-
LRESULT CMainFrame::OnKeyDown(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
{
	LeftRight(wParam);
	return true;
}

void CMainFrame::LeftRight(WPARAM wParam)
{
	wr=phd._WinRight,wl=phd._WinLeft;
	switch(wParam)
	{
	
	case VK_RIGHT:
	{
		work_mtx.lock();// avoid deadlock with the recursion
		string where=phq.Construct(phd._WinRight);
		RF1(where);
	}
	break;
	case VK_LEFT:
	{
		work_mtx.lock();// avoid deadlock with the recursion
		time_duration td=phd._WinRight-phd._WinLeft;
		string where=phq.Construct(phd._WinLeft-td);
		RF1(where);
	}//case VK_LEFT
	}//switch vKey
}//OnKeyDown

//WNDPROC lpfnEditWndProc; // original wndproc for the combo box 
// Prototypes
//LRESULT CALLBACK SubClassProc( HWND, UINT, WPARAM, LPARAM );



LRESULT CMainFrame::OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
			// create command bar window
	HWND hWndCmdBar = m_CmdBar.Create(m_hWnd, rcDefault, NULL, ATL_SIMPLE_CMDBAR_PANE_STYLE);
	// attach menu
	m_CmdBar.AttachMenu(GetMenu());
	// load command bar images
	m_CmdBar.LoadImages(IDR_MAINFRAME);

	// remove old menu
	SetMenu(NULL);

	CreateSimpleStatusBar();

	m_sBar.SubclassWindow(m_hWndStatusBar);
		int arrParts[] = 
		{ 
			ID_DEFAULT_PANE, 
			ID_PANE_1
			};
m_sBar.SetPanes(arrParts, sizeof(arrParts) / sizeof(arrParts[0]), false);

m_sBar.ProgCreate(1 );

	ph_instance._hWnd=m_hWnd;

    HWND hWndToolBar = CreateSimpleToolBarCtrl(m_hWnd, IDR_MAINFRAME, FALSE, ATL_SIMPLE_TOOLBAR_PANE_STYLE);// | TBSTYLE_LIST | CCS_ADJUSTABLE);
	
	CreateSimpleReBar(ATL_SIMPLE_REBAR_NOBORDER_STYLE);
	AddSimpleReBarBand(hWndCmdBar);
	AddSimpleReBarBand(hWndToolBar, NULL, TRUE);
	
	m_Combo = CreateToolbarComboBox(hWndToolBar, ID_PLACEHOLDER,16,16,CBS_DROPDOWN);
	
	ph_instance._hWndStatusBar=m_hWndStatusBar;
	/*HWND hEdit=	FindWindowEx(m_Combo.m_hWnd,NULL,"Edit",NULL);
	 lpfnEditWndProc = (WNDPROC) ::SetWindowLongPtr(hEdit, 
                GWLP_WNDPROC, (LONG_PTR) CMainFrame::SubClassProc);*/

	 /*string pu;
	  GetProcessUser( GetCurrentProcess() ,pu);
        ph_instance.SetUser(  pu);
        ph_instance.SetUserID(LookUpUser());*/

	CMessageLoop* pLoop = _Module.GetMessageLoop();
	ATLASSERT(pLoop != NULL);
	pLoop->AddMessageFilter(this);
		
	SIZE s;
	s.cx=s.cy=0;
	
	phs.SetSize(s);

	/*CHANGEFILTERSTRUCT cfs = { sizeof(CHANGEFILTERSTRUCT) };
	ChangeWindowMessageFilterEx ( m_hWnd, m_uTaskbarBtnCreatedMsg,
                                MSGFLT_ALLOW, &cfs );*/
								//m_vSplit.Create(*this,rcDefault,NULL,WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);
								 m_wndHorzSplit.Create (*this , rcDefault );

	m_hWndClient=m_wndHorzSplit;
	phs.Create(m_wndHorzSplit, rcDefault, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, WS_EX_CLIENTEDGE);
	phti.Create(m_wndHorzSplit, rcDefault, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, WS_EX_CLIENTEDGE);
		//phexec.Create(m_vSplit);//,rcDefault);
		 
	m_wndHorzSplit.SetSplitterPanes(phs,phti);
//m_vSplit.SetSplitterPanes(m_wndHorzSplit,phexec.m_hWnd);
//m_vSplit.SetSplitterPos(500);


	Gdiplus::GdiplusStartupInput gdiplusStartupInput;
   
   
   // Initialize GDI+.
	Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
	return 0;
}

/*select processes that start,end or overlap the times*/
string ModifiedConstruct(ptime Begin,ptime end)
{
	string SQL=" WHERE ";	
	//ptime end=phd.GetEndTime(Begin);
	ostringstream os;
	string begin_txt=BoostToSQLite(Begin),end_txt=BoostToSQLite(end);

	//assert(!begin_txt.empty() || !end_txt.empty());
	os<<"SELECT JULIANDAY('"	<< begin_txt	<<"'),JULIANDAY('"
	<<end_txt	<<"');";

	sqlite3 *db;
	sqlite3_stmt* stmt;
	string ejtxt,bjtxt;

	db = OpenDB();
	if(sqlite3_prepare(db,os.str().c_str(),-1,&stmt,NULL)!=SQLITE_OK)
		DBError(sqlite3_errmsg(db),__LINE__,__FILE__);

	const unsigned char *bjul=0;
	const unsigned char *ejul=0;
	
	if(sqlite3_step(stmt)== SQLITE_ROW )
	{	
		bjul =sqlite3_column_text(stmt,0);		
		ejul =sqlite3_column_text(stmt,1);
	}
	//assert(!bjul==0 || !ejul==0);
	if(bjul==0 || ejul==0)
		PHTrace("Error constructing query",__LINE__,__FILE__);
	ejtxt=(char*)ejul;
	bjtxt=(char*)bjul;
	sqlite3_finalize(stmt);
	sqlite3_close(db);

	os.str("");
	/*Starts within times - events too*/
	os<<"( CreationTime>"	<<bjtxt	<<" AND CreationTime<"	<<ejtxt

	/*Ends within times*/
	<<" AND Destruction NOTNULL ) OR ( Destruction<"	<<ejtxt	<<" AND Destruction>"	<<bjtxt
	<<" AND Destruction NOTNULL)";

	/*Overlaps times*/
		os<<" OR ( CreationTime<"	<<bjtxt	<<" AND Destruction>"	<<ejtxt
		<<" AND Destruction NOTNULL) ";

	if(phd.filter_exec)
		os<< "AND CRC="<<phd.filterCRC<<" ";
	if(phd.filter_user)
		os<<"AND USERID="<<phd.filterUserID<<" ";
	SQL+=os.str();
	return SQL;
}

struct Worker4Thread
{
	date start;
	CComboBox m_Combo;
	string s;
	//CComPtr<ITaskbarList3> m_pTaskbarList;
	HWND h;
	CMPSBarWithProgress* m_sBar;
};

void Worker4(Worker4Thread w4t)
{
	mutex::scoped_lock sl(work_mtx);
	month_iterator titr(w4t.start,1);
	//w4t.m_pTaskbarList->SetProgressState ( w4t.h, TBPF_NORMAL );
	w4t.m_sBar->ProgSetRange(0,12);
	for(;titr<=date(lexical_cast<int>(w4t.s),12,31);++titr)
	{
		ostringstream os;
		os<<"SELECT ID FROM Process"
			<<	ModifiedConstruct(ptime(*titr,minutes(0)),ptime(*titr+months(1),minutes(0)));
		os<<";";
		
		sqlite3 *db=OpenDB();
		sqlite3_stmt* stmt;
		if(sqlite3_prepare(db,os.str().c_str(),-1,&stmt,NULL)!=SQLITE_OK)
			DBError(sqlite3_errmsg(db),__LINE__,__FILE__);

		date monthit=*titr;
			
		if(sqlite3_step(stmt)== SQLITE_ROW )
			w4t.m_Combo.AddString(to_iso_extended_string(monthit).substr(0,7).c_str());
			
		sqlite3_finalize(stmt);
		sqlite3_close(db);		
		/*if ( w4t.m_pTaskbarList )
		{
			w4t.m_pTaskbarList->SetProgressValue ( w4t.h, monthit.month(), 12 );	
         // HRESULT hr=  w4t.m_pTaskbarList->SetProgressState ( w4t.h, TBPF_NOPROGRESS );
		 // PHCOMError(hr,"Error setting progress",__LINE__,__FILE__);
		}		*/
		w4t.m_sBar->ProgSetPos(monthit.month());
	}
	w4t.m_sBar->ProgSetPos(0);
	/*if ( w4t.m_pTaskbarList )
	w4t.m_pTaskbarList->SetProgressValue ( w4t.h,0,12);*/
	//w4t.m_pTaskbarList->SetProgressState ( w4t.h, TBPF_NOPROGRESS );
}

void Worker7(Worker4Thread w4t)
{
	mutex::scoped_lock sl(work_mtx);
	day_iterator ditr(w4t.start);
	w4t.m_sBar->ProgSetRange(0,w4t.start.end_of_month().day());
	//w4t.m_pTaskbarList->SetProgressState ( w4t.h, TBPF_NORMAL );
	for(;ditr<=w4t.start.end_of_month();++ditr)
	{
		ostringstream os;
		os<<"SELECT ID FROM Process"
		<<	ModifiedConstruct(ptime(*ditr,minutes(0)),ptime(*ditr+days(1),minutes(0)));
		os<<";";
		sqlite3 *db=OpenDB();
		sqlite3_stmt* stmt;
		if(sqlite3_prepare(db,os.str().c_str(),-1,&stmt,NULL)!=SQLITE_OK)
			DBError(sqlite3_errmsg(db),__LINE__,__FILE__);
		if(sqlite3_step(stmt)== SQLITE_ROW )
			w4t.m_Combo.AddString(to_iso_extended_string(*ditr).c_str());
		sqlite3_finalize(stmt);
		sqlite3_close(db);		
		/*if ( w4t.m_pTaskbarList )
			w4t.m_pTaskbarList->SetProgressValue ( w4t.h, ditr->day(), w4t.start.end_of_month().day() );*/
		w4t.m_sBar->ProgSetPos(ditr->day());
	}
	w4t.m_sBar->ProgSetPos(0);
	//w4t.m_pTaskbarList->SetProgressState ( w4t.h, TBPF_NOPROGRESS );
	/*if ( w4t.m_pTaskbarList )
	w4t.m_pTaskbarList->SetProgressValue ( w4t.h,0,30);*/
}
/*Would have to do further work for each ROW returned to find out when any processes start in hour*/
void Worker10(Worker4Thread w4t)
{
	mutex::scoped_lock sl(work_mtx);
	time_iterator hitr(ptime(w4t.start),hours(1));
	w4t.m_Combo.ResetContent();
	w4t.m_sBar->ProgSetRange(0,24);
	//w4t.m_pTaskbarList->SetProgressState ( w4t.h, TBPF_NORMAL );
	for(;hitr<ptime(w4t.start,hours(24));++hitr)
	{
		ostringstream os;
		os<<"SELECT DATETIME(CreationTime) FROM Process"
			<<	ModifiedConstruct(*hitr,(*hitr)+hours(1));
		os<<";";
		sqlite3 *db=OpenDB();
		sqlite3_stmt* stmt;
		if(sqlite3_prepare(db,os.str().c_str(),-1,&stmt,NULL)!=SQLITE_OK)
			DBError(sqlite3_errmsg(db),__LINE__,__FILE__);
				//PHTrace(os.str(),__LINE__,__FILE__);
		if(sqlite3_step(stmt)== SQLITE_ROW )
		{
			const unsigned char * firstinhour=0;
			firstinhour = sqlite3_column_text(stmt,0);
			ptime start_in_hour;
			if(firstinhour!=0)
			{
				try
				{
					start_in_hour=time_from_string((const char *)firstinhour);
				}
				catch(std::exception &)
				{
					PHTrace("time_from_string failed",__LINE__,__FILE__);
				}
				if(start_in_hour>=*hitr && start_in_hour<=*hitr+hours(1))
					w4t.m_Combo.AddString(to_iso_extended_string(start_in_hour).replace(10,1," ").substr(0,16).c_str());
				else
					w4t.m_Combo.AddString(to_iso_extended_string(*hitr).replace(10,1," ").substr(0,16).c_str());
			}
		}
		sqlite3_finalize(stmt);
		sqlite3_close(db);	
		/*if ( w4t.m_pTaskbarList )
			w4t.m_pTaskbarList->SetProgressValue ( w4t.h,hitr->time_of_day().hours(), 24);*/
		w4t.m_sBar->ProgSetPos(hitr->time_of_day().hours());
	}
	w4t.m_sBar->ProgSetPos(0);
	//w4t.m_pTaskbarList->SetProgressState ( w4t.h, TBPF_NOPROGRESS );
	/*if ( w4t.m_pTaskbarList )
			w4t.m_pTaskbarList->SetProgressValue ( w4t.h,0,24);*/
}

void CMainFrame::ParseQry()
{
	char q[100];
	int ql=m_Combo.GetWindowTextLength();
	switch(ql)
	{
	case 16:
		work_mtx.lock();// avoid deadlock with the recursion
		DateTimeQry();
	break;
	case 4://year list months with data
	{
		m_Combo.GetWindowText(q,ql+1);
		string s=string(q);
		//iterate through creating date time in SQL for begin /end of each month with in year, if any results add to drop down
		date start;
		try
		{
			start=date(lexical_cast<int>(s),1,1);
		}
		catch(...)
		{
			::SetWindowText(ph_instance._hWndStatusBar,"Input expected YYYY");
			return;
		}
		
		m_Combo.ResetContent();
		Worker4Thread w4t;
		w4t.m_Combo=m_Combo;
		w4t.s=s;
		w4t.start=start;
		//w4t.m_pTaskbarList=m_pTaskbarList;
		w4t.h=m_hWnd;
		w4t.m_sBar=&m_sBar;
		thread st(&Worker4,w4t);
		
	}
	break;
	case 7://year-mm list days
	{
		m_Combo.GetWindowText(q,ql+1);
		string s=string(q);
		
		m_Combo.ResetContent();
		date start;
		try
		{
			s+="-01";
			start=from_string(s);
		}
		catch(...)
		{
			::SetWindowText(ph_instance._hWndStatusBar,"Input expected YYYY-MM");
			return;
		}
		Worker4Thread w4t;
		w4t.m_Combo=m_Combo;
		w4t.start=start;
		//w4t.m_pTaskbarList=m_pTaskbarList;
		w4t.h=m_hWnd;
		w4t.m_sBar=&m_sBar;
		thread st(&Worker7,w4t);
	}
	break;
	case 10://year-mm-dd list hours in drop down
	{
		m_Combo.GetWindowText(q,ql+1);
		string s=string(q);
		ostringstream os;
		date startd;
		try
		{
		startd=from_string(s);
		}
		catch(...)
		{
			::SetWindowText(ph_instance._hWndStatusBar,"Input expected YYYY-MM-DD");
			return;
		}
		Worker4Thread w4t;
		w4t.m_Combo=m_Combo;
		w4t.start=startd;
		//w4t.m_pTaskbarList=m_pTaskbarList;
		w4t.h=m_hWnd;
		w4t.m_sBar=&m_sBar;
		thread st(&Worker10,w4t);
	}
	break;
	}
}

/*LRESULT CALLBACK CMainFrame::SubClassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) 
{ 		
    switch (msg) 
    {         
		case WM_CHAR: 
			//{
				
            switch (wParam) 
            { 

                case VK_RETURN: 

					ParseQry();
                    return 0; 
            }
			//}
    } 
 
    // Call the original window procedure for default processing. 
 
    return CallWindowProc(lpfnEditWndProc, hwnd, 
        msg, wParam, lParam); 
}*/

LRESULT CMainFrame::OnHelpAbout(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
	AboutCtrl ctrl;
	ctrl.DoModal();
	return 0;
}


LRESULT CMainFrame::OnViewKey(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
			/*uses about dialog code as both dialogs have the same function*/
	KeyCtrl ctrl;
	ctrl.DoModal();
	return 0;
}

LRESULT CMainFrame::OnProcessViewSelected(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
	if(phd._selected>0)
	{
		//FoundProcess(phd._selected);
		phti._ID=phd._selected;
		phti.DisplayInfo();
	}
	return 0;
}
#include <boost/filesystem.hpp>
LRESULT CMainFrame::OnExecRunSel(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
	if(phd._selected>0)
	{
		map<long,string>::iterator qpit=phd.qrypaths.find(phd._selected);
		if(qpit!=phd.qrypaths.end())
		{
			if ( boost::filesystem::exists(qpit->second))
			{
			if((int)ShellExecute(NULL, "Open",qpit->second.c_str(),NULL,NULL,SW_SHOWDEFAULT)<33)
				PHTrace(Win32Error(),__LINE__,__FILE__);
			}
			else
				MessageBox("The executable no longer exists","Executable no longer exists",MB_OK);
		}
	}
	return 0;
}

LRESULT CMainFrame::OnExecOCF(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
	string command;
	command ="/select,";
	if(phd._selected>0)
	{
		map<long,string>::iterator qpit=phd.qrypaths.find(phd._selected);
		if(qpit!=phd.qrypaths.end())
		{
			if ( boost::filesystem::exists(qpit->second))
			{
			command +=qpit->second;
			
			// open the containing folder
			if((int)ShellExecute(NULL, "Open", "Explorer", command.c_str(), 
                                                        NULL, SW_SHOWDEFAULT)<33)
				PHTrace(Win32Error(),__LINE__,__FILE__);
			}
			else
				MessageBox("The executable no longer exists","Executable no longer exists",MB_OK);
		}
	}
	return 0;
}

LRESULT CMainFrame::OnGotoEnd(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
	map<long,PHProcess>::iterator it=phq._Processes.find(phd._selected);
	if(it!=phq._Processes.end())
	{
		work_mtx.lock();
		string where=phq.Construct(it->second.end);
		RF1(where);
	}
	return 0;
}

LRESULT CMainFrame::OnGotoBegin(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
	map<long,PHProcess>::iterator it=phq._Processes.find(phd._selected);
	if(it!=phq._Processes.end())
	{
		work_mtx.lock();
		string where=phq.Construct(it->second.start);
		RF1(where);
	}
	return 0;
}

LRESULT CMainFrame::PHTBQry(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
	//work_mtx.lock();
	ParseQry();
	return 0;
}

LRESULT CMainFrame::PHTBLeft(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{	
	if(phd._complete)
	{
		//work_mtx.lock();
		LeftRight(VK_LEFT);
	}
	return 0;
}

LRESULT CMainFrame::PHTBRight(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
	if(phd._complete)
	{
		//work_mtx.lock();
		LeftRight(VK_RIGHT);
	}
	return 0;
}

//LRESULT CMainFrame::OnUser(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
/*{
		SettingsDlg ctrl;
	ctrl.DoModal();
	return 0;
}*/

LRESULT CMainFrame::GoToMostRecent(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{	
	sqlite3 *db=OpenDB();
	sqlite3_stmt* stmt;
	if(sqlite3_prepare(db,"SELECT DATETIME(MAX(Destruction)) FROM Process;",-1,&stmt,NULL)!=SQLITE_OK)
		DBError(sqlite3_errmsg(db),__LINE__,__FILE__);
	if(sqlite3_step(stmt)== SQLITE_ROW )
	{
		work_mtx.lock();
		string file=(char*)sqlite3_column_text(stmt,0);
		//subtract sreen width
		RECT r;
		::GetWindowRect(ph_instance._hWnd,&r);
		int _Width=r.right-r.left;
		float MinutesWide=(float)_Width/60;
		string where=phq.Construct(time_from_string(file)-time_duration(0,(int)MinutesWide,0));
		//worker_mtx.lock();
		RF1(where);
	}
	sqlite3_finalize(stmt);

	sqlite3_close(db);
	return 0;
}

LRESULT CMainFrame::URLHelp(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
	if((int)ShellExecute(NULL, "Open","http://www.stetka.plus.com/PHUser.html",NULL,NULL,SW_SHOWDEFAULT)<33)
		PHTrace(Win32Error(),__LINE__,__FILE__);
	return 0;
}

LRESULT CMainFrame::OnFilterUser(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
	if(phd._selected>0)
	{
		ostringstream os2;
		os2<<"SELECT UserID FROM Process WHERE ID= "<<phd._selected<<";";
		sqlite3 *db2=OpenDB();
		sqlite3_stmt* stmt2;
		if(sqlite3_prepare(db2,os2.str().c_str(),-1,&stmt2,NULL)!=SQLITE_OK)
			DBError(sqlite3_errmsg(db2),__LINE__,__FILE__);
		const unsigned char *user;
		
		if(sqlite3_step(stmt2)== SQLITE_ROW )
		{
			/*user=sqlite3_column_text(stmt2,0);
			string usertxt=(char*)user;*/
			//phd.filtered_user=usertxt;
			phd.filterUserID=sqlite3_column_int(stmt2,0);
			phd.filter_user=true;
			work_mtx.lock();
			DateTimeQry();
			phti._ID=phd._selected;
			phti.DisplayInfo();
		}
		sqlite3_finalize(stmt2);
		sqlite3_close(db2);
	}
	return 0;
}

LRESULT CMainFrame::OnFilterExecutable(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
	if(phd._selected>0)
	{
		ostringstream os2;
		os2<<"SELECT CRC FROM Process WHERE ID="<<phd._selected<<";";
		sqlite3 *db2=OpenDB();
		sqlite3_stmt* stmt2;
		if(sqlite3_prepare(db2,os2.str().c_str(),-1,&stmt2,NULL)!=SQLITE_OK)
			DBError(sqlite3_errmsg(db2),__LINE__,__FILE__);
		if(sqlite3_step(stmt2)== SQLITE_ROW )
		{
			phd.filterCRC=sqlite3_column_int(stmt2,0);
			phd.filter_exec=true;
			work_mtx.lock();
			DateTimeQry();
			phti._ID=phd._selected;
			phti.DisplayInfo();
		}
		sqlite3_finalize(stmt2);

		sqlite3_close(db2);
	}
	return 0;
}

LRESULT CMainFrame::OnClearUserFilter(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
	phd.filter_user=false;
	work_mtx.lock();
	DateTimeQry();
	phti.DisplayInfo();
	return 0;
}

LRESULT CMainFrame::OnClearExecFilter(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
	phd.filter_exec=false;
	work_mtx.lock();
	DateTimeQry();
	phti.DisplayInfo();
	return 0;
}

LRESULT CMainFrame::OnClearAllFilter(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
	phd.filter_user=false;
	phd.filter_exec=false;
	work_mtx.lock();
	DateTimeQry();
	phti.DisplayInfo();
	return 0;
}

/*LRESULT CMainFrame::OnTaskbarBtnCreated ( UINT uMsg, WPARAM wParam, LPARAM lParam )
{
	DWORD dwMajor = LOBYTE(LOWORD(GetVersion()));
DWORD dwMinor = HIBYTE(LOWORD(GetVersion()));
 
  // Check that the OS is Win 7 or later (Win 7 is v6.1).
  if ( dwMajor > 6 || ( dwMajor == 6 && dwMinor > 0 ) )
    {
  m_pTaskbarList.Release();
  m_pTaskbarList.CoCreateInstance ( CLSID_TaskbarList );
  }
  return 0;
}*/
//LRESULT CMainFrame::OnDownloadProgress (UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
/*{
ULONG ulProgress = (ULONG) wParam, ulProgressMax = (ULONG) lParam;
bool bIsMarquee = (m_cProgress.GetStyle() & PBS_MARQUEE) != 0;

    if ( 0 == ulProgressMax )
        {
        // We don't know the size of the file, so put the progress bars into
        // marquee mode to indicate an indeterminate state.
        if ( m_pTaskbarList )
            m_pTaskbarList->SetProgressState ( m_hWnd, TBPF_INDETERMINATE );

       if ( !bIsMarquee )
            {
            m_cProgress.ModifyStyle ( 0, PBS_MARQUEE );
            m_cProgress.SetMarquee ( TRUE, 100 );
            }
        }
    else
        {
        // SetProgressValue automatically cancels the TBPF_INDETERMINATE state if
        // the progress bar is currently in that state.
        if ( m_pTaskbarList )
            m_pTaskbarList->SetProgressValue ( m_hWnd, ulProgress, ulProgressMax );

        if ( bIsMarquee )
            m_cProgress.ModifyStyle ( PBS_MARQUEE, 0 );

        m_cProgress.SetPos ( MulDiv ( ulProgress, 100, ulProgressMax ) );
       }

    return 0;
}*/